﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Mimas.Framework.Shared.Data.DataTransferObjects;
using Mimas.Framework.Shared.Data.EnumObjects;
using Mimas.Framework.Shared.Data.CriteriaObjects;
using Mimas.Framework.Server.DomainObjects;
using Mimas.Framework.Server.DomainObjects.Mapping;
using System.Data.Entity;
using Mimas.Core.Current;
using System.ServiceModel;
using Mimas.Core.Utility;

namespace Mimas.Framework.Server.AdminManagement
{
  public static class ConstantManagementBL
  {
    public static LookupListDTO[] SearchLookupLists(LookupListCO criteria)
    {
      List<LookupListDTO> result = new List<LookupListDTO>();

      if (Constants.Lookuplists == null || !Constants.Lookuplists.Any())
      {
        using (MIMASEntities db = new MIMASEntities())
        {
          DbSet<LookupList> LookupListSet = db.Set<LookupList>();
          DbSet<LookupListItem> LookupListItemSet = db.Set<LookupListItem>();

          var Linq = from ll in LookupListSet
                     join lli in LookupListItemSet
                     on ll.Id equals lli.LookupListId into Items
                     select new { Lists = ll, Items };

          var LinqResult = Linq.ToArray();
          if (LinqResult != null && LinqResult.Any())
          {
            result = LookupListMapping.Map(LinqResult.Select(x => x.Lists).ToArray()).ToList();
            foreach (var item in result)
            {
              if (!LinqResult.Any(x => x.Lists.Id == item.Id)) continue;
              item.Children = LookupListItemMapping.Map(LinqResult.FirstOrDefault(x => x.Lists.Id == item.Id).Items.ToArray());
              foreach (var item2 in item.Children)
              {
                if (!LinqResult.FirstOrDefault(x => x.Lists.Id == item.Id).Items.Any(x => x.Id == item2.Id)) continue;
                item2.Languages = LookupListItemLangMapping.Map(LinqResult.FirstOrDefault(x => x.Lists.Id == item.Id).Items.FirstOrDefault(x => x.Id == item2.Id).Languages.ToArray());
              }
            }
          }
        }
        Constants.Lookuplists = Toolkit.CloneStaticItems<LookupListDTO[]>(result.ToArray());
      }
      else

        result = Toolkit.CloneStaticItems<List<LookupListDTO>>(Constants.Lookuplists.ToList());

      if (criteria.LookupListIds != null && criteria.LookupListIds.Any())
        result = result.Where(x => criteria.LookupListIds.Contains(x.Id)).ToList();

      return result.ToArray();
    }

    public static CountryDTO[] SearchCountries(CountryCO criteria)
    {
      List<CountryDTO> result = new List<CountryDTO>();

      if (Constants.Countries == null || !Constants.Countries.Any())
      {
        using (MIMASEntities db = new MIMASEntities())
        {
          DbSet<Country> CountrySet = db.Set<Country>();

          var Linq = from cc in CountrySet select cc;

          var LinqResult = Linq.ToArray();
          if (LinqResult != null && LinqResult.Any())
          {
            result = CountryMapping.Map(LinqResult).ToList();
            foreach (var item in result)
            {
              item.Languages = CountryLangMapping.Map(LinqResult.FirstOrDefault(x => x.Id == item.Id).Languages.ToArray());
            }
          }
        }
        Constants.Countries = Toolkit.CloneStaticItems<CountryDTO[]>(result.ToArray());
      }
      else
        result = Toolkit.CloneStaticItems<List<CountryDTO>>(Constants.Countries.ToList());

      if (criteria.CountryIds != null && criteria.CountryIds.Any())
        result = result.Where(x => criteria.CountryIds.Contains(x.Id)).ToList();

      return result.ToArray();
    }

    public static TownDTO[] SearchTowns(TownCO criteria)
    {
      List<TownDTO> result = new List<TownDTO>();

      if (Constants.Towns == null || !Constants.Towns.Any())
      {
        using (MIMASEntities db = new MIMASEntities())
        {
          DbSet<Town> TownSet = db.Set<Town>();

          var Linq = from tt in TownSet select tt;

          var LinqResult = Linq.ToArray();
          if (LinqResult != null && LinqResult.Any())
          {
            result = TownMapping.Map(LinqResult.Where(x => !x.ParentId.HasValue).ToArray()).ToList();
            foreach (var item in result)
            {
              if (!LinqResult.Any(x => x.ParentId == item.Id)) continue;
              item.Children = TownMapping.Map(LinqResult.Where(x => x.ParentId == item.Id).ToArray());
            }
          }
        }

        Constants.Towns = Toolkit.CloneStaticItems<TownDTO[]>(result.ToArray());
      }
      else
        result = Toolkit.CloneStaticItems<List<TownDTO>>(Constants.Towns.ToList());

      if (criteria.CountryIds != null && criteria.CountryIds.Any())
        result = result.Where(x => criteria.CountryIds.Contains(x.CountryId ?? 0)).ToList();
      else
        result = result.Where(x => x.CountryId == 1).ToList();

      if (criteria.TownIds != null && criteria.TownIds.Any())
        result = result.Where(x => criteria.TownIds.Contains(x.Id)).ToList();

      if (!criteria.GetChildren)
        result.ForEach(x => x.Children = null);

      return result.ToArray();
    }

    public static MenuItemDTO[] SearchMenus(MenuItemCO criteria)
    {
      List<MenuItemDTO> result = new List<MenuItemDTO>();

      if (Constants.MenuItems == null || !Constants.MenuItems.Any())
      {
        using (MIMASEntities db = new MIMASEntities())
        {
          DbSet<MenuItems> MenuItemsSet = db.Set<MenuItems>();

          var Linq = from mi in MenuItemsSet select mi;

          var LinqResult = Linq.ToArray();
          if (LinqResult != null && LinqResult.Any())
          {
            result = MenuItemMapping.Map(LinqResult).ToList();
          }
        }

        Constants.MenuItems = Toolkit.CloneStaticItems<MenuItemDTO[]>(result.ToArray());
      }
      else
        result = Toolkit.CloneStaticItems<List<MenuItemDTO>>(Constants.MenuItems.ToList());

      if (criteria.MenuItemIds != null && criteria.MenuItemIds.Any())
        result = result.Where(x => criteria.MenuItemIds.Contains(x.Id)).ToList();

      if (criteria.IsActive.HasValue)
        result = result.Where(x => x.IsActive == criteria.IsActive).ToList();

      return result.ToArray();
    }

    public static AccessDTO[] SearchAccessLists(AccessListCO criteria)
    {
      List<AccessDTO> result = new List<AccessDTO>();

      if (Constants.AccessLists == null || !Constants.AccessLists.Any())
      {
        using (MIMASEntities db = new MIMASEntities())
        {
          DbSet<AccessList> AccessListSet = db.Set<AccessList>();

          var Linq = from al in AccessListSet select al;

          var LinqResult = Linq.ToArray();
          if (LinqResult != null && LinqResult.Any())
          {
            result = AccessListMapping.Map(LinqResult).ToList();
          }
        }

        Constants.AccessLists = Toolkit.CloneStaticItems<AccessDTO[]>(result.ToArray());
      }
      else
        result = Toolkit.CloneStaticItems<List<AccessDTO>>(Constants.AccessLists.ToList());

      if (criteria.AccessListIds != null && criteria.AccessListIds.Any())
        result = result.Where(x => criteria.AccessListIds.Contains(x.Id)).ToList();

      if (criteria.IsAccessable.HasValue)
        result = result.Where(x => x.IsAccessable == criteria.IsAccessable).ToList();

      if (criteria.UserType.HasValue)
        result = result.Where(x => x.UserType == criteria.UserType).ToList();

      return result.ToArray();
    }


  }
}
